use chrono::prelude::*;
use chrono::{NaiveDate, NaiveDateTime, NaiveTime, Duration};

/// 工具类 `DateUtil` 用于处理日期和时间相关操作
pub struct DateUtil;

impl DateUtil {
    /// 获取当前本地时间并格式化为字符串
    ///
    /// # 返回值
    /// 返回当前本地时间的字符串表示，格式为 "YYYY-MM-DD HH:MM:SS"
    ///
    /// # 示例
    /// ```
    /// let current_time = DateUtil::now();
    /// log::info!("Current Time: {}", current_time);
    /// ```
    pub fn now() -> String {
        let now: DateTime<Local> = Local::now();
        now.format("%Y-%m-%d %H:%M:%S").to_string()
    }

    /// 格式化给定的日期时间为指定格式的字符串
    ///
    /// # 参数
    /// * `date` - 需要格式化的日期时间
    /// * `format` - 格式字符串
    ///
    /// # 返回值
    /// 返回格式化后的日期时间字符串
    ///
    /// # 示例
    /// ```
    /// let now = Local::now();
    /// let formatted_date = DateUtil::format_date(&now, "%Y-%m-%d %H:%M:%S");
    /// log::info!("Formatted Date: {}", formatted_date);
    /// ```
    pub fn format_date(date: &DateTime<Local>, format: &str) -> String {
        date.format(format).to_string()
    }

    /// 将指定格式的字符串解析为日期时间
    ///
    /// # 参数
    /// * `date_str` - 日期时间字符串
    /// * `format` - 格式字符串
    ///
    /// # 返回值
    /// 返回解析后的日期时间，如果解析失败则返回 `None`
    ///
    /// # 示例
    /// ```
    /// let parsed_date = DateUtil::parse_date("2024-07-10 12:34:56", "%Y-%m-%d %H:%M:%S");
    /// match parsed_date {
    ///     Some(date) => log::info!("Parsed Date: {}", date),
    ///     None => log::info!("Failed to parse date"),
    /// }
    /// ```
    pub fn parse_date(date_str: &str, format: &str) -> Option<DateTime<Local>> {
        match Local.datetime_from_str(date_str, format) {
            Ok(datetime) => Some(datetime),
            Err(_) => None,
        }
    }

    /// 获取当前日期并格式化为字符串
    ///
    /// # 返回值
    /// 返回当前日期的字符串表示，格式为 "YYYY-MM-DD"
    ///
    /// # 示例
    /// ```
    /// let today = DateUtil::today();
    /// log::info!("Today: {}", today);
    /// ```
    pub fn today() -> String {
        let today: NaiveDateTime = Local::now().naive_local();
        today.format("%Y-%m-%d").to_string()
    }

    /// 计算两个日期之间的天数差
    ///
    /// # 参数
    /// * `start_date` - 起始日期
    /// * `end_date` - 结束日期
    ///
    /// # 返回值
    /// 返回两个日期之间的天数差
    ///
    /// # 示例
    /// ```
    /// let start_date = NaiveDate::from_ymd(2023, 7, 1);
    /// let end_date = NaiveDate::from_ymd(2024, 7, 1);
    /// let days_diff = DateUtil::days_between(&start_date, &end_date);
    /// log::info!("Days Between: {}", days_diff);
    /// ```
    pub fn days_between(start_date: &NaiveDate, end_date: &NaiveDate) -> i64 {
        (*end_date - *start_date).num_days()
    }

    /// 获取当前日期时间并添加指定的天数
    ///
    /// # 参数
    /// * `days` - 要添加的天数
    ///
    /// # 返回值
    /// 返回添加指定天数后的日期时间
    ///
    /// # 示例
    /// ```
    /// let future_date = DateUtil::add_days(30);
    /// log::info!("Future Date: {}", future_date);
    /// ```
    pub fn add_days(days: i64) -> DateTime<Local> {
        Local::now() + Duration::days(days)
    }

    /// 获取当前日期时间并减去指定的天数
    ///
    /// # 参数
    /// * `days` - 要减去的天数
    ///
    /// # 返回值
    /// 返回减去指定天数后的日期时间
    ///
    /// # 示例
    /// ```
    /// let past_date = DateUtil::subtract_days(30);
    /// log::info!("Past Date: {}", past_date);
    /// ```
    pub fn subtract_days(days: i64) -> DateTime<Local> {
        Local::now() - Duration::days(days)
    }

    /// 获取当前时间并格式化为字符串
    ///
    /// # 返回值
    /// 返回当前时间的字符串表示，格式为 "HH:MM:SS"
    ///
    /// # 示例
    /// ```
    /// let current_time_str = DateUtil::current_time();
    /// log::info!("Current Time: {}", current_time_str);
    /// ```
    pub fn current_time() -> String {
        let now: NaiveTime = Local::now().time();
        now.format("%H:%M:%S").to_string()
    }

    /// 将字符串解析为日期
    ///
    /// # 参数
    /// * `date_str` - 日期字符串，格式为 "YYYY-MM-DD"
    ///
    /// # 返回值
    /// 返回解析后的日期，如果解析失败则返回 `None`
    ///
    /// # 示例
    /// ```
    /// let parsed_date = DateUtil::parse_naive_date("2024-07-03");
    /// match parsed_date {
    ///     Some(date) => log::info!("Parsed Date: {}", date),
    ///     None => log::info!("Failed to parse date"),
    /// }
    /// ```
    pub fn parse_naive_date(date_str: &str) -> Option<NaiveDate> {
        match NaiveDate::parse_from_str(date_str, "%Y-%m-%d") {
            Ok(date) => Some(date),
            Err(_) => None,
        }
    }

    /// 将字符串解析为时间
    ///
    /// # 参数
    /// * `time_str` - 时间字符串，格式为 "HH:MM:SS"
    ///
    /// # 返回值
    /// 返回解析后的时间，如果解析失败则返回 `None`
    ///
    /// # 示例
    /// ```
    /// let parsed_time = DateUtil::parse_naive_time("15:30:00");
    /// match parsed_time {
    ///     Some(time) => log::info!("Parsed Time: {}", time),
    ///     None => log::info!("Failed to parse time"),
    /// }
    /// ```
    pub fn parse_naive_time(time_str: &str) -> Option<NaiveTime> {
        match NaiveTime::parse_from_str(time_str, "%H:%M:%S") {
            Ok(time) => Some(time),
            Err(_) => None,
        }
    }
}

fn main() {
    // 获取当前本地时间并格式化为字符串
    let current_time = DateUtil::now();
    log::info!("Current Time: {}", current_time);

    // 获取当前日期并格式化为字符串
    let today = DateUtil::today();
    log::info!("Today: {}", today);

    // 计算两个日期之间的天数差
    let start_date = NaiveDate::from_ymd_opt(2023, 7, 1);
    let end_date = NaiveDate::from_ymd_opt(2024, 7, 1);
    let days_diff = DateUtil::days_between(&start_date.unwrap(), &end_date.unwrap());
    log::info!("Days Between: {}", days_diff);

    // 获取当前日期时间并添加指定的天数
    let future_date = DateUtil::add_days(30);
    log::info!("Future Date: {}", future_date);

    // 获取当前日期时间并减去指定的天数
    let past_date = DateUtil::subtract_days(30);
    log::info!("Past Date: {}", past_date);

    // 获取当前时间并格式化为字符串
    let current_time_str = DateUtil::current_time();
    log::info!("Current Time: {}", current_time_str);

    // 将字符串解析为日期
    let parsed_date = DateUtil::parse_naive_date("2024-07-03");
    log::info!("Parsed Date: {:?}", parsed_date);

    // 将字符串解析为时间
    let parsed_time = DateUtil::parse_naive_time("15:30:00");
    log::info!("Parsed Time: {:?}", parsed_time);
}